NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name [GMT] New forum posts indicator // @namespace https://greasyfork.org/users/321857-anakunda // @version 1.03.0 // @author Anakunda // @copyright © 2020-2024, Anakunda (https://greasyfork.org/users/321857-anakunda) // @license GPL-3.0-or-later // @match https://*/forums.php?action=viewthread&threadid=* // @match https://*/forums.php?page=*&action=viewthread&threadid=* // @grant GM_getValue // @grant GM_setValue // @require https://openuserjs.org/src/libs/Anakunda/libLocks.min.js // @require https://openuserjs.org/src/libs/Anakunda/gazelleApiLib.min.js // @description Indicate a forum thread has received new post(s) while idling on any thread page // ==/UserScript== 'use strict'; const postBody = document.getElementById('quickpost'); if (postBody == null) throw 'Post body missing'; const replyControls = document.body.querySelector('form#quickpostform > div.preview_submit'); if (replyControls == null) throw 'Reply controls missing'; const urlParams = new URLSearchParams(document.location.search); const threadId = parseInt(urlParams.get('threadid')); if (!(threadId > 0)) throw 'Thread Id missing'; const page = parseInt(urlParams.get('page')) || 1; const getThreadCounts = (page = 9999999) => queryAjaxAPI('forum', { type: 'viewthread', threadid: threadId, page: page }).then(response => ({ posts: response.posts.length, currentPage: response.currentPage, pages: response.pages, })); const interval = GM_getValue('check_interval', 15), snapshot = getThreadCounts(); let newPostsIndicator = null, activeTimer; const checkPosts = () => snapshot.then(snapshot => getThreadCounts(snapshot.currentPage).then(function(response) { if (response.pages <= snapshot.pages && response.posts <= snapshot.posts) return; clearInterval(activeTimer); activeTimer = undefined; if (!newPostsIndicator) { (newPostsIndicator = document.createElement('span')).style = 'margin-left: 3em; color: darkorange;'; replyControls.append(newPostsIndicator); } else newPostsIndicator.innerHTML = ''; const link = document.createElement('a'), onLastPage = page >= snapshot.pages; if (response.pages > page && !(onLastPage && response.posts > snapshot.posts)) { link.href = '/forums.php'; link.search = new URLSearchParams({ action: 'viewthread', threadid: response.threadId, page: onLastPage ? page + 1 : response.pages, }); link.textContent = `go to ${onLastPage ? 'next' : 'last'} page`; } else { link.href = '#'; link.onclick = function(evt) { document.location.reload(); return false; }; link.textContent = 'refresh page'; } newPostsIndicator.append('This thread received new post(s) [', link, ']'); })); postBody.onfocus = function(evt) { if (activeTimer != undefined || newPostsIndicator) return; activeTimer = setInterval(checkPosts, interval * 1000); checkPosts(); }; postBody.onblur = function(evt) { if (activeTimer != undefined) clearInterval(activeTimer); else return; activeTimer = undefined; };